package com.xiaotu.common.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.xiaotu.common.util.Glyph;
import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.util.FontUtils;
import com.xiaotu.common.util.XMLUtil;

import org.apache.commons.lang.StringUtils;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.Connection.Response;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.selector.Html;

/**
 * @类名 PageUtils
 * @日期 2017年2月13日
 * @作者 高海军
 * @功能 爬取页面处理帮助类
 */
public class PageUtils
{
    /**
     * 添加新的爬取链接
     *
     * @param page     page对象
     * @param requests 链接列表
     * @param extraMap 辅助信息
     */
    public static void addTargetRequests(Page page, List<String> requests,
            Map<String, Object> extraMap)
    {
        if (page == null || requests == null || requests.isEmpty())
            return;
        for (String request : requests)
            addTargetRequest(page, request, extraMap);
    }

    /**
     * 添加新的爬取链接
     *
     * @param page     page对象
     * @param request  链接
     * @param extraMap 辅助信息
     */
    public static void addTargetRequest(Page page, String request,
            Map<String, Object> extraMap)
    {
        if (page == null || StringUtils.isEmpty(request))
            return;

        Request req = new Request(request);
        req.setExtras(extraMap);
        req.setPriority(page.getRequest().getPriority());
        page.addTargetRequest(req);
    }

    public static void addTargetRequest(Page page, String request,
            Map<String, Object> extraMap, boolean newExtra)
    {
        Map<String, Object> newExtraMap = extraMap;
        if (newExtra)
        {
            newExtraMap = new HashMap<>();
            newExtraMap.putAll(extraMap);
        }
        addTargetRequest(page, request, newExtraMap);
    }

    public static Map<String, Object> getNewExtraMapFromPage(Page page, String[] newKeys, Object[] newValues)
    {
        Map<String, Object> map = new HashMap<>();
        map.putAll(page.getRequest().getExtras());
        for (int i = 0; i < newKeys.length; i++)
            map.put(newKeys[i], newValues[i]);
        return map;
    }


    public static Html getFontData(Page page)
    {
        String reqData = page.getHtml().xpath("//style[@id='js-nuwa']").get();
        if (StringUtils.isEmpty(reqData))
            throw new SpiderException(SpiderExceptionCode.DataInvalideException);
        reqData = reqData.substring(reqData.indexOf(";base64,") + ";base64,".length(), reqData
                .indexOf(") format(\"woff\")"));
        Map<String, String> map = new HashMap<>();
        map.put("base64", reqData);
        String code = HttpUtils.httpPostJSONP("http://192.168.10.134:3001", map);
        if (StringUtils.isEmpty(code))
            throw new SpiderException(SpiderExceptionCode.DataInvalideException);
        Map<String, Object> resMap = GsonUtils.fromJson(code, Map.class);
        if (0 != (Double) resMap.get("code"))
            throw new SpiderException(SpiderExceptionCode.DataInvalideException, (String) resMap
                    .get("message"));
        resMap.remove("code");
        resMap.remove("message");

        String htmlStr = page.getRawText();
        for (Map.Entry<String, Object> entry : resMap.entrySet())
            htmlStr = StringUtils.replace(htmlStr, entry.getKey().toLowerCase(), entry.getValue()
                    + "");
        return new Html(htmlStr);
    }
    
    
    public static Html spiderAudienceRating (Page page,Map<String,String> cookies) {
    	String convertHtmlStr = "";
    	try {
    		Connection conn = Jsoup.connect(page.getRequest().getUrl())   
                    .userAgent("Mozilla/5.0 (Windows NT 6.1; rv:47.0) Gecko/20100101 Firefox/47.0") // http请求的浏览器设置
                    .timeout(5000)   // http连接时长
                    .maxBodySize(0)
                    .method(Connection.Method.GET)
                    .cookies(cookies);
    		conn.get();
    		Response rs = conn.response();
    		String html = rs.body();
    		html = html.replaceAll("&#x", "");//防止加密内容被转义
    		Document doc = Jsoup.parse(html);
    		//从response中获取base64Text
    	    Element head = doc.head(); 
            String style = head.getElementById("js-nuwa").toString(); 
            String base64Text = style.substring(style.indexOf("base64,")+7, style.indexOf(") format"));
            //调用python服务，将base64Text转换成xml文件格式字符串      	
    		String xmlStr  = readFont(base64Text);       
            //获取xmlStr中的密文与对应像素点轮廓数据
    		org.dom4j.Document document = XMLUtil.parseXML(xmlStr);	
    		List<Glyph> glyphList = FontUtils.buildGlyphList(document);	
    		
    		//获取预设的明文与对应像素点轮廓数据
    		InputStream in=XMLUtil.class.getResourceAsStream("/maoyanfont.xml");   	
    		org.dom4j.Document setDocument = XMLUtil.getDocument(in);
    		List<Glyph> setGlyphList = FontUtils.buildGlyphList(setDocument);
    		//循环对比glyph和setGlyph，计算出本次密文与明文的映射关系
    		Map<String,String> codeMap = new HashMap<String,String>();
    		for(Glyph glyph: glyphList) {
//    			for(Glyph setGlyph: setGlyphList) {
//    				if(glyph.equals(setGlyph)) {
//    					codeMap.put(glyph.getName().replace("uni", "").toLowerCase(), setGlyph.getId());
//    					break;
//    				}
//    			}
    			Glyph matchGlyph = glyph.match(setGlyphList);
    			if(null != matchGlyph){
    				codeMap.put(glyph.getName().replace("uni", "").toLowerCase(), matchGlyph.getId());
    			}
    			
    		}
    		
    		//调试用，查看本次密文与明文的映射关系
//    		for(Map.Entry<String,String> entry : codeMap.entrySet()) {
//    			System.out.println(entry.getKey()+"解密为"+entry.getValue());
//    		}
    		//从response中获取待解密的数据
    		Element body = doc.body();
    		convertHtmlStr = body.toString();
    		for (Map.Entry<String, String> entry : codeMap.entrySet())
    			convertHtmlStr = StringUtils.replace(convertHtmlStr, entry.getKey().toLowerCase()+";", entry.getValue()
                        + "");
		} catch (Exception e) {
			e.printStackTrace();
		}
    	return new Html(convertHtmlStr);
    }
    
    
    public static Html spiderAudienceRating (String html,String style) {
    	String convertHtmlStr = "";
    	try {
    		html = html.replaceAll("&#x", "");//防止加密内容被转义		
    		Document doc = Jsoup.parse(html);
    		//从response中获取base64Text
            String base64Text = style.substring(style.indexOf("base64,")+7, style.indexOf(") format"));
            //调用python服务，将base64Text转换成xml文件格式字符串      	
    		String xmlStr  = readFont(base64Text);	     
      
            //获取xmlStr中的密文与对应像素点轮廓数据
    		org.dom4j.Document document = XMLUtil.parseXML(xmlStr);	
    		List<Glyph> glyphList = FontUtils.buildGlyphList(document);	
    		
    		//获取预设的明文与对应像素点轮廓数据
    		InputStream in=XMLUtil.class.getResourceAsStream("/maoyanfont.xml");   	
    		org.dom4j.Document setDocument = XMLUtil.getDocument(in);
    		List<Glyph> setGlyphList = FontUtils.buildGlyphList(setDocument);
    		//循环对比glyph和setGlyph，计算出本次密文与明文的映射关系
    		Map<String,String> codeMap = new HashMap<String,String>();
    		for(Glyph glyph: glyphList) {
    			for(Glyph setGlyph: setGlyphList) {
    				if(glyph.equals(setGlyph)) {
    					codeMap.put(glyph.getName().replace("uni", "").toLowerCase(), setGlyph.getId());
    					break;
    				}
    			}
    		}
    		
    		//调试用，查看本次密文与明文的映射关系
//    		for(Map.Entry<String,String> entry : codeMap.entrySet()) {
//    			System.out.println(entry.getKey()+"解密为"+entry.getValue());
//    		}
    		//从response中获取待解密的数据
    		Element body = doc.body();
    		convertHtmlStr = body.toString();
    		for (Map.Entry<String, String> entry : codeMap.entrySet())
    			convertHtmlStr = StringUtils.replace(convertHtmlStr, entry.getKey().toLowerCase()+";", entry.getValue()
                        + "");
		} catch (Exception e) {
			e.printStackTrace();
		}
    	return new Html(convertHtmlStr);
    }
    
    
    
    public static String readFont(String base64string) {
    	String responseBody = null ;
    	String url = "http://139.129.11.229:8080/woff";   	
    	try {
    		Connection conn =Jsoup.connect(url)    
    		        .userAgent("Mozilla/5.0 (Windows NT 6.1; rv:47.0) Gecko/20100101 Firefox/47.0") // http请求的浏览器设置
    		        .timeout(60000)   // http连接时长
    		        .maxBodySize(0)
    		        .method(Connection.Method.POST); 
			conn.data("base64string", base64string);
			conn.post();
			responseBody = conn.response().body();	
		} catch (IOException e) {
			e.printStackTrace();
		}
    	return responseBody;
    }

}
